/**
 * Copyright (c) 2022 Presto Labs Pte. Ltd.
 * Author: Ju
 */

#pragma once

#include <deque>

#include "coin2/base/memory/mem_slice.h"

namespace coin2::controller {
using namespace coin2::base;

class MessageAssembler {
 public:
  class Callback {
   public:
    virtual ~Callback() = default;
    virtual void OnProcessMessage(memory::MemSlice data) = 0;
    virtual void OnBroken() = 0;
  };
  explicit MessageAssembler(Callback *callback);
  ~MessageAssembler() = default;

  void OnPacketReceived(memory::MemSlice payload);

 private:
  bool GetPacketLength(uint16_t *length);
  void CheckCompleteness();
  memory::MemSlice TakeBuffer(uint32_t bytes_needed);

 private:
  std::deque<memory::MemSlice> slices_;
  uint32_t queueing_bytes_;
  Callback *callback_;
};
}  // namespace coin2::controller